// 回归分析 Regression.vue
<template>
  <div class="tab-pane fit relative-position">
    <!-- search box -->
    <q-list highlight separator class="search-box">
      <q-item class="bg-white" @click.native="changeFuns">
        <q-item-main>
          <span>{{ $t('模型选择') }}：</span>
          <span style="float: right;">{{ funsAction.label }}</span>
        </q-item-main>
        <q-item-side right>
          <q-item-tile icon="navigate_next" color="green"/>
        </q-item-side>
      </q-item>
      <q-item class="bg-white">
        <q-item-main>
          <span>{{ $t('预测天数') }}：</span>
          <!-- <span style="float: right;">{{ '5' }}</span> -->
          <q-input
            type="number"
            v-model="funsNum"
            align="right"
            style="float: right;"
            hide-underline
          />
        </q-item-main>
        <q-item-side right>
          <!-- <q-item-tile icon="navigate_next" color="green" /> -->
          <span>{{ $t('天') }}</span>
        </q-item-side>
      </q-item>
    </q-list>
    <line-chart :chartData="chartData" :customOptions="customOptions" height="300px"></line-chart>

    <!--
      将QInnerLoading放置为最后一个子元素。
      这对于将其显示在其他内容之上很重要。
    -->
    <q-inner-loading :visible="tabPaneLoading">
      <template v-if="tabPaneLoadingContent">{{ tabPaneLoadingContent }}</template>
      <q-spinner-gears v-else size="50px" color="primary"></q-spinner-gears>
    </q-inner-loading>
  </div>
</template>

<script>
import { debounce } from 'quasar'
export default {
  name: 'regression',
  data() {
    return {
      tabPaneLoading: true,
      tabPaneLoadingContent: '',
      funsActionSheetOptions: {
        title: this.$t('请选择需要绘制的函数'),
        grid: false,
        actions: []
      },
      funsAction: {},
      funsNum: 5,
      chartData: {
        typeData: [],
        valueData: []
      },
      customOptions: {
        title: {
          show: true,
          text: '',
          textStyle: {
            fontSize: 13
          }
        },
        xAxis: {
          type: "time",
          splitLine: {
            show: false
          }
        },
        yAxis: {
          type: "value",
          splitLine: {
            show: true
          },
          axisLabel: {
            formatter: "{value} mm"
          }
        },
      }
    }
  },
  watch: {
    funsNum: {
      type: Number,
      handler: debounce(function (val, oldVal) {
        this.showChart();
      }, 1000)
    }
  },
  mounted() {
    this.getFunctions();
  },
  props: {
    dealData: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  methods: {
    getFunctions() {
      return this.$axios.getFunctions({
        wsguid: this.dealData.detailInfo.wsguid,
        csecid: this.dealData.detailInfo.csecid,
        point_alias: this.dealData.label
      }).then(result => {
        let funList = ((data) => {
          let arr = [];
          // 指数
          if (data.model_exp && data.model_exp !== "NA") {
            arr.push({
              label: this.$t("指数"),
              key: "exp",
              model: data.model_exp,
              score: Number(data.score_exp)
            });
          }
          // 对数
          if (data.model_log && data.model_log !== "NA") {
            arr.push({
              label: this.$t("对数"),
              key: "log",
              model: data.model_log,
              score: Number(data.score_log)
            });
          }
          // 双曲线
          if (data.model_hyperbolic && data.model_hyperbolic !== "NA") {
            arr.push({
              label: this.$t("双曲线"),
              key: "hyperbolic",
              model: data.model_hyperbolic,
              score: Number(data.score_hyperbolic)
            });
          }
          // sort 按照分数
          arr.sort(function (a, b) {
            return b.score - a.score;
          });
          return arr;
        })(result.data || {});
        //
        if(funList.length <= 0) {
          throw new Error();
        }
        //
        this.funsAction = funList[0] || {};
        this.funsActionSheetOptions.actions = funList;
        this.showChart();
        // this.tabPaneLoading = false;
      }).catch(err => {
        this.tabPaneLoadingContent = err.msg || this.$t('没有回归分析数据');
      });
    },
    getSurveyData() {
      return this.$axios.getSurveyData({
        data: {
          eq_csecid: this.dealData.detailInfo.csecid,
          eq_csec_name: this.dealData.detailInfo.csec_name,
          eq_point_alias: this.dealData.label,
          page: 1,
          size: 5
        }
      }).then(res => {
        let data = (function (_da) {
          // 升序排序
          _da.sort(function (a, b) {
            return a.surveytime > b.surveytime ? 1 : -1;
          });
          return _da;
        })(res.data || []);
        if (data.length < 5) {
          this.tabPaneLoadingContent = this.$t('量测数据少于${num}期', {num: 5});
          return false;
        }
        return data;
      }).catch(() => {
        this.tabPaneLoadingContent = this.$t('没有量测数据，无法进行分析');
      });
    },
    changeFuns() {
      this.$q.actionSheet(this.funsActionSheetOptions).then(action => {
        this.funsAction = action;
        this.showChart();
      }).catch(err => err);
    },
    drawLine(data) {
      // 绘图数据--真实数据、预测数据
      let cumu = [], cumu_other = [];
      // 预测天数
      let date = this.funsNum, last_day = 0, firstDate = new Date(data[0].surveytime);
      /** 函数转换-可执行 */
      let fun = this.funsAction.model
      fun = fun.split("=")[1];
      fun = fun.replace(" ", "");
      fun = fun.replace("exp", "Math.exp");
      fun = fun.replace("log10", "Math.log10");
      fun = fun.replace("ln", "Math.log2");
      fun = fun.replace("--", "+");
      fun = fun.replace("++", "+");
      // 幂函数
      fun = (function (s) {
        let reg = /(t{0,1}(\d*\.\d*){0,1})\^(\d+)/,
          tmpV;
        do {
          tmpV = reg.exec(s);
          if (tmpV) {
            s = s.replace(
              tmpV[0],
              "Math.pow(" + tmpV[1] + "," + tmpV[tmpV.length - 1] + ")"
            );
          }
        } while (tmpV);
        return s;
      })(fun);
      /* e */
      // 数据
      data.forEach(function (val, index) {
        let t = new Date(new Date(val.surveytime) - firstDate);
        t = t / 1000 / 60 / 60 / 24;
        cumu.push({
          name: val.surveytime,
          value: [val.surveytime, Number(val.cumu) * 1000]
        });
        cumu_other.push({
          name: val.surveytime,
          value: [val.surveytime, t === 0 ? "-" : eval(fun).toFixed(2)]
        });
        last_day = t;
      });
      // 预测
      if (date > 0) {
        let lastTime = new Date(
          cumu_other[cumu_other.length - 1].name
        ).getTime();
        for (var i = 1, t, tmp; i <= date; i++) {
          t = last_day + i;
          tmp = this.$formatDate(new Date(lastTime + i * 24 * 60 * 60 * 1000), "YYYY-MM-DD HH:mm:ss");
          cumu_other.push({
            name: tmp,
            value: [tmp, eval(fun).toFixed(2)]
          });
        }
      }
      // draw
      this.customOptions.title.text = this.$t('回归函数') + "：" + this.funsAction.model;// 标题函数
      this.chartData.valueData = [
        {
          name: this.$t('预测数据'),
          data: cumu_other,
          lineStyle: {
            normal: {
              color: "#FF0000"
            }
          },
          symbol: "none", //这句就是去掉点的
          smooth: true //这句就是让曲线变平滑的
        },
        {
          name: this.$t('量测数据'),
          data: cumu,
          lineStyle: {
            normal: {
              color: "#555"
            }
          }
        }
      ]
    },
    showChart() {
      this.tabPaneLoading = true;
      this.getSurveyData().then(res => {
        if (res) {
          this.drawLine(res)
          this.tabPaneLoading = false;// 删除加载动画
        }
      });
    }

  }
}
</script>

<style lang="less" scoped>
.tab-pane {
  .search-box {
    border: none;
    padding: 0;
    margin-bottom: 10px;
  }

  .q-inner-loading {
    background-color: rgba(255, 255, 255, 1);
  }
}
</style>

